﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MarvinsArena.Core;
using MarvinsArena.Robot.Core;

namespace BattleLogic
{
	public class Robot:IRobot, ILogicObject
	{
		//private event EventHandler<MessageExchangeFromRobotEventArgs> handleRobotEvents;


        public string Name { get; set; }
        public double PositionX { get { return this.RobotHost.PositionX; } set { this.RobotHost.PositionX = value; } }
        public double PositionY { get { return this.RobotHost.PositionY; } set { this.RobotHost.PositionY = value; } }
        public double Radius { get; set; }
        public double Rotation { get { return this.RobotHost.Rotation; } set { this.RobotHost.Rotation = value; } }
        public TypeWorldObjects TypeWorldObject { get { return TypeWorldObjects.Robot; } }

        public RobotHost RobotHost { get; set; }
        public double RotationGun { get { return this.RobotHost.RotationGun; } set { this.RobotHost.RotationGun = value; } }
        public double RotationRadar { get { return this.RobotHost.RotationRadar; } set { this.RobotHost.RotationRadar = value; } }
        public int SquadNumber { get { return this.RobotHost.SquadNumber; } set { this.SquadNumber = value; } }
        public int Team { get { return this.RobotHost.Team; } set { this.Team = value; } }
        public string FullName { get { return String.Format("{0} {1}.{2}", this.RobotHost.Name, this.RobotHost.Team, this.RobotHost.SquadNumber); } set { this.FullName = value; } }
        public int Hitpoints { get { return this.RobotHost.Hitpoints; } set { this.Hitpoints = value; } }
        public int Missiles { get { return this.RobotHost.Missiles; } set { this.Missiles = value; } }
        public int Heat { get { return this.RobotHost.Heat; } set { this.Heat = value; } }
        public bool IsActive { get { return this.RobotHost.IsActive; } set { this.IsActive = value; } }
        public string DisabledMessage { get { return this.RobotHost.DisabledMessage; } set { this.DisabledMessage = value; } }

		public event EventHandler<MessageExchangeFromRobotEventArgs> HandleRobotEvents;

		public bool Dead { get; set; }


		public Robot(IRobot robot)
		{
			
			Dead = false;
           
            this.RobotHost = robot.RobotHost;
        }

		public bool TargetInScannerRange(IWorldObject target)
		{
			double scanRadius = 0.69813170079773183076947630739545; //40°
			double scanRadiusHalf = scanRadius / 2.0;

			double scannerAngleInRad = this.RotationRadar - scanRadiusHalf;
			double scannerAngleInRad2 = this.RotationRadar + scanRadiusHalf;
			double angleBetweenObjects = Math.Atan2(target.PositionY - this.PositionY, target.PositionX - this.PositionX);

			if (angleBetweenObjects >= scannerAngleInRad && angleBetweenObjects <= scannerAngleInRad2)
				return true;

			if (scannerAngleInRad < -Math.PI && angleBetweenObjects == Math.PI && target.PositionX < this.PositionX)
				return true;

			return false;
		}

		public void Update(double deltaTime)
		{
			System.Threading.Thread threadRun = new System.Threading.Thread(this.RobotHost.Run);
			threadRun.Start();

			if (CoreMain.Instance.Timeout)
			{
				// Terminate after 250ms
				if (!threadRun.Join(250))
				{
					this.RobotHost.Disable("Timeout of 250ms reached");
				}
			}
			else
			{
				threadRun.Join();
			}

			MessageExchangeFromRobotEventArgs ex = this.RobotHost.Update(deltaTime);

			if (this.HandleRobotEvents != null)
			{
				this.HandleRobotEvents(this, ex);
			}
		}

		public void NotifyMessageToTeammate(CoreMessageReceivedFromTeammateEventArgs msg)
		{
			this.RobotHost.NotifyMessageToTeammate(msg);
		}

		public void NotifyCollision(Collision collision)
		{
			this.RobotHost.NotifyCollision(collision);
		}

		public void NotifyTarget(ScannerTarget scannerTarget)
		{
			this.RobotHost.NotifyTarget(scannerTarget);
		}

		public void Notify()
		{
			this.RobotHost.Notify();
		}

		public void SetRoundValues(TournamentRules rules)
		{
			this.RobotHost.SetRoundValues(rules.Hitpoints, rules.Missiles, rules.MaxHeat);
		}

		public static bool operator ==(Robot robot1, Robot robot2)
		{
			if (robot1.PositionX == robot2.PositionX && robot1.PositionY == robot2.PositionY &&
				robot1.FullName == robot2.FullName)
				return true;

			return false;
		}

		public static bool operator !=(Robot robot1, Robot robot2)
		{
			return !(robot1 == robot2);
		}

		public override bool Equals(object obj)
		{
			return this == (Robot)obj;
		}

		
	}
}
